/*
 * $Id: mstring.h,v 1.31 2006-04-06 16:25:37 bacon Exp $
 */

#ifndef _XP_BAS_MSTRING_H_
#define _XP_BAS_MSTRING_H_

#include <xp/types.h>
#include <xp/macros.h>
#include <xp/bas/stdarg.h>

#define XP_MSTRFNMAT_PATHNAME (1 << 0)
#define XP_MSTRFNMAT_NOESCAPE (1 << 1)
#define XP_MSTRFNMAT_PERIOD   (1 << 2)
#define XP_MSTRFNMAT_CASEFOLD (1 << 3)

typedef struct xp_mvstr_t xp_mvstr_t;

struct xp_mvstr_t
{
	xp_mchar_t   buffer_space[256];
	xp_mchar_t*  buffer;
	xp_size_t    buffer_capacity;
	xp_size_t    buffer_ubound;

	xp_mchar_t*  vector_space[64 + 1];
	xp_mchar_t** vector;
	xp_size_t    vector_capacity;
	xp_size_t    vector_ubound;

	xp_bool_t __dynamic;
};

#ifdef __cplusplus
extern "C" {
#endif

xp_size_t xp_mstrlen (const xp_mchar_t* str);
xp_size_t xp_mstrsize (const xp_mchar_t* str);  /* xp_mstrlen + 1 */
xp_size_t xp_mstrlenn (const xp_mchar_t* str, xp_size_t max);
xp_size_t xp_mstrsizen (const xp_mchar_t* str, xp_size_t max);

xp_size_t xp_mstrset (xp_mchar_t* buf, xp_mchar_t c, xp_size_t n);
xp_size_t xp_mstrxset (xp_mchar_t* buf, xp_size_t bsz, xp_mchar_t c, xp_size_t n);

xp_size_t xp_mstrcpy (xp_mchar_t* buf, const xp_mchar_t* str);
xp_size_t xp_mstrcpyn (xp_mchar_t* buf, const xp_mchar_t* str, xp_size_t n);
xp_size_t xp_mstrncpy (xp_mchar_t* buf, const xp_mchar_t* str, xp_size_t len);
xp_size_t xp_mstrxcpy (xp_mchar_t* buf, xp_size_t bsz, const xp_mchar_t* str);
xp_size_t xp_mstrxncpy (
	xp_mchar_t* buf, xp_size_t bsz, const xp_mchar_t* str, xp_size_t len);

xp_size_t xp_mstrcat (xp_mchar_t* buf, const xp_mchar_t* str);
xp_size_t xp_mstrcatn (xp_mchar_t* buf, const xp_mchar_t* str, xp_size_t n);
xp_size_t xp_mstrncat (xp_mchar_t* buf, const xp_mchar_t* str, xp_size_t len);
xp_size_t xp_mstrxcat (xp_mchar_t* buf, xp_size_t bsz, const xp_mchar_t* str);
xp_size_t xp_mstrxncat (
	xp_mchar_t* buf, xp_size_t bsz, const xp_mchar_t* str, xp_size_t len);
xp_size_t xp_mstrxapp (xp_mchar_t* buf, xp_size_t size, ...);
xp_size_t xp_mstrxappv (xp_mchar_t* buf, xp_size_t size, xp_va_list ap);
xp_size_t xp_mstrxcap (xp_mchar_t* buf, xp_size_t size, ...);
xp_size_t xp_mstrxcapv (xp_mchar_t* buf, xp_size_t size, xp_va_list ap);

int xp_mstrcmp (const xp_mchar_t* s1, const xp_mchar_t* s2);
int xp_mstrcmpn (const xp_mchar_t* s1, const xp_mchar_t* s2, xp_size_t count);
int xp_mstrxcmp (const xp_mchar_t* s1, xp_size_t len, const xp_mchar_t* s2);
int xp_mstrxncmp (
	const xp_mchar_t* s1, xp_size_t len1, const xp_mchar_t* s2, xp_size_t len2);
int xp_mstrcasecmp (const xp_mchar_t* s1, const xp_mchar_t* s2);
int xp_mstrcasecmpn (const xp_mchar_t* s1, const xp_mchar_t* s2, xp_size_t n);
int xp_mstrncasecmp (const xp_mchar_t* s1, const xp_mchar_t* s2, xp_size_t count);
int xp_mstrxcasecmp (const xp_mchar_t* s1, xp_size_t len, const xp_mchar_t* s2);
int xp_mstrxncasecmp (
	const xp_mchar_t* s1, xp_size_t len1, const xp_mchar_t* s2, xp_size_t len2);

xp_mchar_t* xp_mstrstr (const xp_mchar_t* str, const xp_mchar_t* sub);
xp_mchar_t* xp_mstrxstr (
	const xp_mchar_t* str, xp_size_t size, const xp_mchar_t* sub);
xp_mchar_t* xp_mstrxnstr (const xp_mchar_t* str,
	xp_size_t strsz, const xp_mchar_t* sub, xp_size_t subsz);

xp_mchar_t* xp_mstrrstr (const xp_mchar_t* str, const xp_mchar_t* sub);
xp_mchar_t* xp_mstrxrstr (
	const xp_mchar_t* str, xp_size_t size, const xp_mchar_t* sub);
xp_mchar_t* xp_mstrxnrstr (const xp_mchar_t* str,
	xp_size_t strsz, const xp_mchar_t* sub, xp_size_t subsz);

xp_mchar_t* xp_mstrchr (const xp_mchar_t* str, xp_mcint_t c);
xp_mchar_t* xp_mstrxchr (const xp_mchar_t* str, xp_size_t len, xp_mcint_t c);
xp_mchar_t* xp_mstrrchr (const xp_mchar_t* str, xp_mcint_t c);
xp_mchar_t* xp_mstrxrchr (const xp_mchar_t* str, xp_size_t len, xp_mcint_t c);

xp_mchar_t* xp_mstrpbrk (const xp_mchar_t* str, const xp_mchar_t* needle);
xp_mchar_t* xp_mstrxpbrk (
	const xp_mchar_t* str, xp_size_t n, const xp_mchar_t* needle);
xp_mchar_t* xp_mstrnpbrk (
	const xp_mchar_t* str, const xp_mchar_t* needle, xp_size_t n);
xp_mchar_t* xp_mstrxnpbrk (
	const xp_mchar_t* str, xp_size_t n1, const xp_mchar_t* needle, xp_size_t n2);

xp_mchar_t* xp_mstrrpbrk (const xp_mchar_t* str, const xp_mchar_t* needle);
xp_mchar_t* xp_mstrxrpbrk (
	const xp_mchar_t* str, xp_size_t n, const xp_mchar_t* needle);
xp_mchar_t* xp_mstrnrpbrk (
	const xp_mchar_t* str, const xp_mchar_t* needle, xp_size_t n);
xp_mchar_t* xp_mstrxnrpbrk (
	const xp_mchar_t* str, xp_size_t n1, const xp_mchar_t* needle, xp_size_t n2);

xp_size_t xp_mstrspn (
	const xp_mchar_t* str1, const xp_mchar_t* str2);
xp_size_t xp_mstrxspn (
	const xp_mchar_t* str1, xp_size_t n1, const xp_mchar_t* str2);
xp_size_t xp_mstrnspn (
	const xp_mchar_t* str1, const xp_mchar_t* str2, xp_size_t n2);
xp_size_t xp_mstrxnspn (
	const xp_mchar_t* str1, xp_size_t n1, const xp_mchar_t* str2, xp_size_t n2);

xp_size_t xp_mstrcspn (
	const xp_mchar_t* str1, const xp_mchar_t* str2);
xp_size_t xp_mstrxcspn (
	const xp_mchar_t* str1, xp_size_t n1, const xp_mchar_t* str2);
xp_size_t xp_mstrncspn (
	const xp_mchar_t* str1, const xp_mchar_t* str2, xp_size_t n2);
xp_size_t xp_mstrxncspn (
	const xp_mchar_t* str1, xp_size_t n1, const xp_mchar_t* str2, xp_size_t n2);

xp_size_t xp_mstrrot (xp_mchar_t* str, int dir, xp_size_t n);
xp_size_t xp_mstrxrot (xp_mchar_t* str, xp_size_t len, int dir, xp_size_t n);
xp_size_t xp_mstrrev (xp_mchar_t* str);
xp_size_t xp_mstrxrev (xp_mchar_t* str, xp_size_t len);

xp_mchar_t* xp_mstrdup (const xp_mchar_t* str);
xp_mchar_t* xp_mstrxdup (const xp_mchar_t* str, xp_size_t len);
xp_mchar_t* xp_mstrxdup2 (
	const xp_mchar_t* str1, xp_size_t len1,
	const xp_mchar_t* str2, xp_size_t len2);

xp_size_t xp_mstrdel (xp_mchar_t* str, xp_size_t pos, xp_size_t n);
xp_size_t xp_mstrxdel (xp_mchar_t* str, xp_size_t len, xp_size_t pos, xp_size_t n);
xp_size_t xp_mstrrmchr (xp_mchar_t* str, xp_mcint_t c);
xp_size_t xp_mstrxrmchr (xp_mchar_t* str, xp_size_t len, xp_mcint_t c);

xp_bool_t xp_mstristype (
	const xp_mchar_t* str, xp_bool_t(*ctype_func)(xp_mcint_t c));
xp_bool_t xp_mstrxistype (
	const xp_mchar_t* str, xp_size_t len, xp_bool_t(*ctype_func)(xp_mcint_t c));

xp_size_t xp_mstrupr (xp_mchar_t* str);
xp_size_t xp_mstrxupr (xp_mchar_t* str, xp_size_t len);
xp_size_t xp_mstrlwr (xp_mchar_t* str);
xp_size_t xp_mstrxlwr (xp_mchar_t* str, xp_size_t len);

xp_size_t xp_mstrtrm (xp_mchar_t* str);
xp_size_t xp_mstrxtrm (xp_mchar_t* str, xp_size_t len);
xp_size_t xp_mstrpac (xp_mchar_t* str);
xp_size_t xp_mstrxpac (xp_mchar_t* str, xp_size_t len);

xp_mchar_t* xp_mstrtok  (
	const xp_mchar_t*, const xp_mchar_t*, xp_mchar_t**, xp_size_t*);
xp_mchar_t* xp_mstrxtok (const xp_mchar_t* s, xp_size_t len,
	const xp_mchar_t* delim, xp_mchar_t** tok, xp_size_t* tok_len);

int xp_mstrspl (xp_mchar_t* s, const xp_mchar_t* delim, 
	xp_mchar_t lquote, xp_mchar_t rquote, xp_mchar_t escape, xp_size_t* count);
int xp_mstrspls (
	xp_mchar_t* s, const xp_mchar_t* delim, xp_mchar_t lquote, xp_mchar_t rquote, 
	xp_mchar_t escape, xp_size_t* count, xp_mchar_t* ptrs[]);

int xp_mstrfnmat (const xp_mchar_t* str, const xp_mchar_t* ptn, int flags);
xp_bool_t xp_mstrxfnmat  (
	const xp_mchar_t* str, xp_size_t slen, const xp_mchar_t* ptn, int flags);
xp_bool_t xp_mstrnfnmat  (
	const xp_mchar_t* str, const xp_mchar_t* ptn, xp_size_t plen, int flags);
int xp_mstrxnfnmat (
	const xp_mchar_t* str, xp_size_t slen, 
	const xp_mchar_t* ptn, xp_size_t plen, int flags);

xp_size_t xp_mstrtodn (
	const xp_mchar_t* name, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_mstrxtodn (
	const xp_mchar_t* name, xp_size_t nsz, xp_byte_t* buf, xp_size_t bufsz);
xp_size_t xp_mstrfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_mchar_t* buf, xp_size_t bufsz);
xp_size_t xp_mstrxfromdn (
	const xp_byte_t* dn, xp_size_t dnsz, xp_mchar_t* buf, xp_size_t bufsz);

/* string vector functions */
xp_mvstr_t* xp_mvstr_open (xp_mvstr_t* vec);
void xp_mvstr_close (xp_mvstr_t* vec);
void xp_mvstr_clear (xp_mvstr_t* vec);
int xp_mvstr_append (xp_mvstr_t* vec, const xp_mchar_t* str);

#ifdef __cplusplus
}
#endif

#endif
